package com.github.tomakehurst.wiremock.extension.export;

import com.github.tomakehurst.wiremock.common.Json;
import com.github.tomakehurst.wiremock.stubbing.StubMapping;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;

/**
 * 适配版工具类：无 JsonOptions 依赖，手动格式化 JSON
 */
public class StubExportHelper {

    /**
     * 单个 Stub 导出：先序列化为紧凑 JSON，再手动格式化（替代 JsonOptions.prettyPrint()）
     */
    public static byte[] exportSingle(StubMapping stub) {
        if (stub == null) throw new IllegalArgumentException("Stub cannot be null");

        // 1. 用 WireMock 原生 Json 工具序列化（无参方法，返回紧凑 JSON）
        String compactJson = Json.write(stub);
        // 2. 手动格式化 JSON（易读格式，与 prettyPrint 效果一致）
        String prettyJson = formatJson(compactJson);
        // 3. 转为字节数组（用于下载）
        return prettyJson.getBytes(StandardCharsets.UTF_8);
    }

    /**
     * 批量 Stub 导出：复用单个导出逻辑，压缩为 ZIP
     */
    public static byte[] exportBatch(List<StubMapping> stubs) {
        if (stubs.isEmpty()) throw new IllegalArgumentException("Stub list cannot be empty");

        try (ByteArrayOutputStream baos = new ByteArrayOutputStream();
             ZipOutputStream zos = new ZipOutputStream(baos)) {

            for (StubMapping stub : stubs) {
                if (stub == null) continue;
                // 生成规范文件名（处理特殊字符）
                String stubName = stub.getName() == null ? "unknown" : stub.getName().replaceAll("[^a-zA-Z0-9_\\-]", "_");
                String entryName = String.format("stub-%s-%s.json", stub.getId(), stubName);
                // 写入 ZIP 条目
                zos.putNextEntry(new ZipEntry(entryName));
                zos.write(exportSingle(stub)); // 复用格式化后的 JSON
                zos.closeEntry();
            }
            zos.finish();
            return baos.toByteArray();

        } catch (IOException e) {
            throw new RuntimeException("Batch ZIP create failed: " + e.getMessage(), e);
        }
    }

    /**
     * 手动格式化 JSON 字符串（替代 JsonOptions.prettyPrint()）
     * 逻辑：按 {}、[] 自动换行+缩进，确保易读
     */
    private static String formatJson(String compactJson) {
        if (compactJson == null || compactJson.isEmpty()) return "";

        StringBuilder prettyBuilder = new StringBuilder();
        int indentLevel = 0; // 缩进级别
        char[] chars = compactJson.toCharArray();

        for (int i = 0; i < chars.length; i++) {
            char c = chars[i];

            // 遇到 { 或 [：换行 + 当前缩进 + 字符 + 缩进+1
            if (c == '{' || c == '[') {
                prettyBuilder.append("\n").append(getIndent(indentLevel)).append(c).append("\n");
                indentLevel++;
                prettyBuilder.append(getIndent(indentLevel));
            }
            // 遇到 } 或 ]：缩进-1 + 换行 + 缩进 + 字符
            else if (c == '}' || c == ']') {
                indentLevel--;
                prettyBuilder.append("\n").append(getIndent(indentLevel)).append(c);
                // 若下一个字符是 ,：当前行加 , 并换行
                if (i + 1 < chars.length && chars[i + 1] == ',') {
                    prettyBuilder.append(chars[++i]).append("\n").append(getIndent(indentLevel));
                }
            }
            // 遇到 ,：换行 + 当前缩进
            else if (c == ',') {
                prettyBuilder.append(c).append("\n").append(getIndent(indentLevel));
            }
            // 其他字符：直接追加
            else {
                prettyBuilder.append(c);
            }
        }

        return prettyBuilder.toString();
    }

    /**
     * 获取缩进字符串（4个空格为一级，符合 JSON 格式化习惯）
     */
    private static String getIndent(int level) {
        return " ".repeat(level * 4); // JDK 11+ 支持 String.repeat()；若用低版本 JDK，可替换为循环拼接
    }

    // 生成单个导出文件名（不变）
    public static String getSingleFileName(StubMapping stub) {
        String stubName = stub.getName() == null ? "unknown" : stub.getName().replaceAll("[^a-zA-Z0-9_\\-]", "_");
        return String.format("stub-%s-%s.json", stub.getId(), stubName);
    }

    // 生成批量导出文件名（不变）
    public static String getBatchFileName() {
        String timestamp = new SimpleDateFormat("yyyyMMddHHmmss").format(new Date());
        return String.format("stubs-export-%s.zip", timestamp);
    }
}